package com.blog.shiro;

import com.blog.entity.SysUser;
import com.blog.service.Impl.SysUserServiceImpl;
import com.blog.util.DateFormatUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author gxcc3
 * @auther gxcc
 * @create 2021/9/24 21:46
 * 自定义的realm
 */
@Slf4j
public class UserRealm extends AuthorizingRealm {


    @Resource
    SysUserServiceImpl userService;

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("==>shiro  授权doGetAuthenticationInfo");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //获取用户数据
        Subject subject = SecurityUtils.getSubject();
        SysUser sysUser = (SysUser)subject.getPrincipal();

        if (sysUser.isAdmin()){
            info.addRole("admin");
            info.addStringPermission("*:*:*");
        }else {
            // 角色列表
            Set<String> roles = new HashSet<String>();
            // 功能列表
            Set<String> menus = new HashSet<String>();

            roles = userService.selectRoleSign(sysUser.getId());
            menus = userService.selectPermsByUserId(sysUser.getId());
            // 角色加入AuthorizationInfo认证对象
            info.setRoles(roles);
            // 权限加入AuthorizationInfo认证对象
            info.setStringPermissions(menus);
        }
        return info;
    }

    /**
     * 登录认证
     * @param token 封装的用户token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        log.info(" ==>shiro  认证doGetAuthenticationInfo");



        UsernamePasswordToken userToken = (UsernamePasswordToken)token;
        SysUser sysUser = null;
        try {
            sysUser = userService.login(userToken.getUsername(), new String(userToken.getPassword()));

            //登录成功之后将用户信息保存在session中
            Subject currentSubject = SecurityUtils.getSubject();
            Session session = currentSubject.getSession();
            session.setAttribute("user",sysUser);

            //获取创建时间
            String joinTime = DateFormatUtil.dataToStr(sysUser.getCreateTime());
            session.setAttribute("joinTime",joinTime);

        }catch (Exception e){
            throw new AuthenticationException(e.getMessage(), e);
        }

//        SysUser temp;
//        //处理session
//        DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
//        DefaultWebSessionManager sessionManager = (DefaultWebSessionManager) securityManager.getSessionManager();
//        //获取当前已登录的用户session列表
//        Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();
//        //当前session列表的个数
//        int  allUser= sessions.size();
//        for (Session session: sessions){
//            Object attribute = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
//            if(attribute==null){
//                continue;//结束本次循环
//            }
//
//            temp = (SysUser) ((SimplePrincipalCollection) attribute).getPrimaryPrincipal();
//            //判断当前登录的用户是否在线如果在线直接挤掉上一次登录
//            if(userToken.getUsername().equals(temp.getUsername())) {
//                allUser--;
//                sessionManager.getSessionDAO().delete(session);
//            }
//        }

        //shiro处理密码
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(sysUser,sysUser.getPassword(),"");
        return info;
    }
}
